package com.doudou.zuul.filter;

import com.doudou.zuul.config.AppConfig;
import com.doudou.zuul.entity.AppAccess;
import com.doudou.zuul.entity.ZuulResponseConstant;
import com.doudou.zuul.filter.handler.LoginVerifyHandlerChain;
import com.doudou.zuul.utils.ZuulFilterRequestUtils;
import com.doudou.zuul.utils.ZuulFilterResponseUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Base64;

/**
 * 处理登录数据的提交。添加appid
 */
@Component
public class Oauth2RequestFilter extends ZuulFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(Oauth2RequestFilter.class);

    public static final String APP_NAME = "APP_NAME";

    public static final String ATTACH_CERT = "attachCert";

    public static final String DEFAULT_APP_ID = "default";

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private LoginVerifyHandlerChain loginVerifyHandlerChain;

    @Override
    public String filterType() {
        return FilterConstants.ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {

        RequestContext ctx = RequestContext.getCurrentContext();

        if (!ctx.sendZuulResponse()) {
            return false;
        }

        String requestUri = ZuulFilterRequestUtils.getRequestUri(ctx);

        //只路由登录请求
        if (appConfig.getLoginDataUrls().contains(requestUri)) {
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {

        RequestContext ctx = RequestContext.getCurrentContext();

        String appName = ZuulFilterRequestUtils.getRequestHeader(ctx, APP_NAME);
        String requestUri = ZuulFilterRequestUtils.getRequestUri(ctx);

        //如果在header中拿不到，就在请求参数中拿
        if (StringUtils.isEmpty(appName)) {
            appName = ZuulFilterRequestUtils.getRequestParam(ctx, APP_NAME);
        }

        if (StringUtils.isEmpty(appName)) {

            String message = ZuulFilterResponseUtils.viewTipsMessage(
                    appConfig.isEnableLocalLogPrefix(),
                    appConfig.getLocalAppName(),
                    ZuulResponseConstant.ILLEGAL_APP
            );

            //login request ajax
            ZuulFilterResponseUtils.sendResponse(ctx,
                    1000,
                    message,
                    message);

            return null;
        }

        //责任链
        final AppAccess appAccess = loginVerifyHandlerChain.doInvoke(requestUri, appName);

        if (null == appAccess) {

            String message = ZuulFilterResponseUtils.viewTipsMessage(
                    appConfig.isEnableLocalLogPrefix(),
                    appConfig.getLocalAppName(),
                    ZuulResponseConstant.ILLEGAL_APP
            );

            ZuulFilterResponseUtils.sendResponse(ctx,
                    1000,
                    message,
                    message);

            return null;
        }

        //组装oauth2 的必须参数，登录换取token
        String access = appAccess.getAppId() + ":" + appAccess.getAppSecret();
        String basicOauth = "Basic " + new String(Base64.getEncoder().encode(access.getBytes()));
        ctx.addZuulRequestHeader("Authorization", basicOauth);

        //添加appId 用于后台实名认证
        String appId = new String(Base64.getEncoder().encode(DEFAULT_APP_ID.getBytes()));
        if (appAccess.getCertify()) {
            appId = new String(Base64.getEncoder().encode(appAccess.getAppId().getBytes()));
        }

        //用于微信验证
        ctx.addZuulRequestHeader(ATTACH_CERT, appId);
        return null;
    }
}
